AWSアカウントへのサインインやスイッチロールを検知してSlackに通知する
AWSアカウントにサインインやスイッチロールしたことを通知する仕組みを作ってみるのはどうだろう?とふと思ったので、作ってみました。 画面ポチポチではなく、AWS CloudFormationでデプロイします。
おすすめの方
- AWSにサインイン(スイッチロール含む)したとき、Slackに通知する仕組みを知りたい方
- 上記をAWS CloudFormationで作成したい方
- Amazon EventBridgeのAPI destinationsをCloudFormationで作成したい方
前提(大事なこと)
AWS CloudTrailを有効にする
サインインやスイッチロールは、AWS CloudTrailが検知します。 そのため、AWS CloudTrailを有効にしてください。
全リージョンにデプロイする
サインインが記録されるリージョンは、固定ではありません。 そのため、全リージョンにデプロイすることをおすすめします。 もしかしたら、他に良い方法があるかもしれません……。
なお、スイッチロールについては、該当のリージョンおよびバージニア北部(us-east-1)のそれぞれで記録されるようです。
AWSアクセスキーの利用は通知しない
今回の仕組みでは、AWSアクセスキーの利用は通知しません。 AWSアクセスキーの利用も通知したい場合は、下記などを参考にして、Amazon EventBridgeのルールを作成してください。
今回はAWS Chatbotを利用しない(情報が少ないため)
AWS ChatbotでもSlackに通知できますが、「情報が足りない」と思うかもしれません。
具体的には、下記の情報(Amazon EventBridgeのサンプルイベント)がありますが、AWS Chatbotを利用した場合だと知りたいことが少ないと思うかもしれません。
{ "version": "0", "id": "6f87d04b-9f74-4f04-a780-7acf4b0a9b38", "detail-type": "AWS Console Sign In via CloudTrail", "source": "aws.signin", "account": "123456789012", "time": "2016-01-05T18:21:27Z", "region": "us-east-1", "resources": [], "detail": { "eventVersion": "1.02", "userIdentity": { "type": "Root", "principalId": "123456789012", "arn": "arn:aws:iam::123456789012:root", "accountId": "123456789012" }, "eventTime": "2016-01-05T18:21:27Z", "eventSource": "signin.amazonaws.com", "eventName": "ConsoleLogin", "awsRegion": "us-east-1", "sourceIPAddress": "0.0.0.0", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36", "requestParameters": null, "responseElements": { "ConsoleLogin": "Success" }, "additionalEventData": { "LoginTo": "https://console.aws.amazon.com/console/home?state=hashArgs%23&isauthcode=true", "MobileVersion": "No", "MFAUsed": "No" }, "eventID": "324731c0-64b3-4421-b552-dfc3c27df4f6", "eventType": "AwsConsoleSignIn" } }
そのため、本記事では、Amazon EventBridgeからSlackのIncoming WebhookにHTTPリクエストを行いました。
SlackのIncoming WebhookのURLを取得する
次のドキュメントを参考にして、Incoming WebhookのURLを取得します。
動作を確認しておきます。
curl -X POST -H "Content-type: application/json" \ -d '{"text": "Hello, world."}' \ "https://hooks.slack.com/services/aaa/bbb/ccc"
AWSアカウントへのサインインやスイッチロールを検知してSlackに通知する仕組みを作る
CloudFormationテンプレート
Amazon EventBridgeのルールを定義し、API destinationsでSlackに通知します。通知内容などは、必要に応じてカスタマイズしてください。
AWSTemplateFormatVersion: "2010-09-09" Description: Notify slack aws signin stack Parameters: SlackIncomingWebhookUrl: Type: String Resources: SigninEventRule: Type: AWS::Events::Rule Properties: EventPattern: source: - aws.signin detail-type: - AWS Console Sign In via CloudTrail detail: eventSource: - signin.amazonaws.com Targets: - Id: NotifySlackSigninApiDestination Arn: !GetAtt NotifySlackSigninApiDestination.Arn RoleArn: !GetAtt NotifySlackSigninEventRuleRole.Arn InputTransformer: InputPathsMap: account: $.account eventTime: $.detail.eventTime eventName: $.detail.eventName eventID: $.detail.eventID userIdentityType: $.detail.userIdentity.type userIdentityArn: $.detail.userIdentity.arn LoginTo: $.detail.additionalEventData.LoginTo SwitchFrom: $.detail.additionalEventData.SwitchFrom SwitchTo: $.detail.additionalEventData.SwitchTo InputTemplate: > { "blocks": [ { "type": "section", "fields": [ { "type": "mrkdwn", "text": "*eventName:* <eventName>" }, { "type": "mrkdwn", "text": "*eventID:* <eventID>" }, { "type": "mrkdwn", "text": "*account:* <account>" }, { "type": "mrkdwn", "text": "*eventTime:* <eventTime>" }, { "type": "mrkdwn", "text": "*userIdentityType:* <userIdentityType>" }, { "type": "mrkdwn", "text": "*userIdentityArn:* <userIdentityArn>" }, { "type": "mrkdwn", "text": "*LoginTo:* <LoginTo>" }, { "type": "mrkdwn", "text": "*SwitchFrom:* <SwitchFrom>" }, { "type": "mrkdwn", "text": "*SwitchTo:* <SwitchTo>" } ] } ] } NotifySlackSigninEventRuleRole: Type: AWS::IAM::Role Properties: RoleName: !Sub notify-slack-signin-event-rule-${AWS::Region}-role AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: events.amazonaws.com Action: sts:AssumeRole Policies: - PolicyName: "deploy-iam-sample-deploy-policy-for-user" PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: events:InvokeApiDestination Resource: !GetAtt NotifySlackSigninApiDestination.Arn NotifySlackSigninConnection: Type: AWS::Events::Connection Properties: Name: notify-slack-signin-connection AuthorizationType: API_KEY AuthParameters: ApiKeyAuthParameters: ApiKeyName: dummy ApiKeyValue: dummy NotifySlackSigninApiDestination: Type: AWS::Events::ApiDestination Properties: Name: notify-slack-signin-api-destination ConnectionArn: !GetAtt NotifySlackSigninConnection.Arn HttpMethod: POST InvocationEndpoint: !Ref SlackIncomingWebhookUrl
デプロイ
リージョン(us-east-1)とパラメータを指定します。
SlackIncomingWebhookUrl
には、SlackのIncoming WebhookのURLを指定します。
aws cloudformation deploy \ --template-file notify.yaml \ --stack-name notify-slack-aws-signin-chatbot-stack \ --capabilities CAPABILITY_NAMED_IAM \ --region us-east-1 \ --parameter-overrides \ SlackIncomingWebhookUrl="https://hooks.slack.com/services/xxx/yyy/zzz" \ --no-fail-on-empty-changeset
動作確認する
IAMユーザの動作確認は、別途、ap-southeast-2にデプロイして確認しています。
なお、Slackアプリ名が「CircleCI」になっていますが、本実験用に「既存の実験用Slackアプリ(名前:CircelCI)」を利用したためです。気にしないでくださいませ。
サインイン(IMAユーザ)
スイッチロール(IAMロール)
スイッチバック(IAMロール)
さいごに
AWSアカウントへのサインインやスイッチロールをSlackに通知する仕組みをCloudFormationで作ってみました。 具体的な運用ルールなどを設ける必要はありますが、明らかに怪しいアクセス(土日祝など)には気づけると思います。
参考
- Sending messages using Incoming Webhooks | Slack
- 【アップデート】EventBridgeのターゲットにHTTPのエンドポイントが指定可能になったので、EventBridgeから直接SlackのAPIを叩いてみた | DevelopersIO
- Integrating using the new API Destinations of Amazon EventBridge | by Samuel Vandecasteele | Medium
- EventBridge を利用して IAM User の SwitchRole 通知を行う - サーバーワークスエンジニアブログ
- リージョン別サインインイベントのログ記録
- AWS Management Console サインインイベント - AWS CloudTrail
- CloudTrailが記録するConsoleLoginイベントについて | DevelopersIO
- 特定の AWS 認証情報の使用状況を追跡する